<template>
  <div>
    <el-button @click="startMouseAddData(MyMapOpt.MapType.Polygon)" :disabled="mouseToolData.open">添加面</el-button>
    <el-button @click="startMouseAddData(MyMapOpt.MapType.Polyline)" :disabled="mouseToolData.open">添加线</el-button>
    <el-button @click="startMouseAddData(MyMapOpt.MapType.Marker)" :disabled="mouseToolData.open">添加点</el-button>
    <el-button type="primary" icon="el-icon-edit" :disabled="!mouseToolData.type===''" @click="openAddDialog('新增')">添加</el-button>



    <AMapView :updateMap="updateMap" :updateCoordsy="updateCoordsy" :can-change-layer="canChangeLayer"></AMapView>

    <div class="input-card" style='width: 10rem;' v-if="mouseToolData.open">
      <div style="color: red">请在点图中绘制</div>
      <input type="file" accept=".json" v-on:change="addJsonFile"></input>
      <el-input type="text" v-model="mouseToolData.name"  placeholder="要素名称"/>
      <el-button @click="stopMouseAddData(true)">保存</el-button>
      <el-button @click="stopMouseAddData(false)">取消</el-button>
    </div>
    <div v-else>
      <el-tag
          v-for="tag in elementInTop"
          :key="tag.mapData.name"
          :closable="true"
          type=""
          @close="handleClose(tag)"
          @click="moveTo(tag)"
      >
        {{tag.mapData.name}}
      </el-tag>
      <el-table
          :data="[...elementInPage]"
          style="width: 100%;margin-top: 10px"
          border
      >
        <el-table-column
            type="index"
            label="序号"
        ></el-table-column>
        <el-table-column
            label="数据"
            style='overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;'>
          <template v-slot="{$index,row}">
            {{row.mapData.name||row}}<span v-if="row.mapData.top">&#9875;</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{$index,row}">
            <el-button  type="danger" @click="deleteMapData(row)" circle icon="el-icon-delete"></el-button>
            <el-button size="mini" @click="moveTo(row)" circle icon="el-icon-location"></el-button>
            <el-button size="mini" @click="exportJSON(row)" circle icon="el-icon-bottom"></el-button>
          </template>
        </el-table-column>
        <el-table-column label="设置">
          <template v-slot="{$index,row}">
            <el-button class="editAttr" @click="openEditDialog(row,$index)" circle icon="el-icon-setting"/>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          :page-size="pageData.pageSize"
          :pager-count="11"
          :current-page="pageData.currentPage"
          layout="prev, pager, next , ->, total"
          :total="pageData.count"
          @current-change="handleCurrentPageChange"
          @size-change="handlePageSizeChange"
      >
      </el-pagination>
    </div>
<!--  修改数据  -->
    <EditDialog
        v-if="editVisible"
      @save="saveEditDialog"
      />

  </div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader';
import Vue from 'vue';
import _ from "lodash";
import {mapActions, mapGetters, mapMutations, mapState} from "vuex";


import {convert_gcj02_To_Gps84, convert_gps84_To_Gcj02, MyMapOpt} from '@/class/map/myMapOpt'
import {
  reqGetMapdataByPage,
  reqGetMapdataCount,
  reqGetMapDataTop,
} from "@/api/mapdata";
import {requestGetData, requestIsSuccess} from "@/api/request";
import {getRandomColor} from "@/utils/utils";
import {convertGPS2GCJ02} from "@/store/map/map";
import {Polygon, PolygonData} from "@/class/map/Polygon";
import {Polyline, PolylineData} from "@/class/map/Polyline";
import {Marker, MarkerData} from "@/class/map/Maker";
import {MapData} from "@/class/map/MapData";
import {Layer} from "@/class/map/Layer";
import AMapView from "@/views/map/AMapView.vue";
import {TrackData} from "@/class/map/Track";
import EditDialog from "@/views/map/dialog/EditDialog.vue";
import {warningMessage} from "@/utils/message";
import {getMapDateByType} from "@/utils/map";

let map
let geolocation
export default {
  name: "MyMap",
  components: {EditDialog, AMapView},
  data(){

    return{
      //画图要素
      mouseToolData:{
        open:false,
        overlays:[],
        mouseTool:{},
        name:"",
        type:""
      },
      //正在修改的要素
      editDialogData: {
        //编辑图框的显示与关闭
        visible:false,
      },
      canChangeLayer:true,
      pageData:{
        count: 0,
        pageSize: 5,
        currentPage: 1,
      },
      mapCoordSys:MyMapOpt.MapCoordSys.CJ02,
      feature:{
        page:[],
        top:[],
      }
    }
  },
  watch:{
    elementInPage: {
      handler(mapElements) {
        this.feature.page.forEach((item,index)=>{
          const flag = mapElements.forEach(element=>{
            return item.getExtData().id === element.mapData.id;
          })
          if(flag===undefined){
            item.remove();
            this.feature.page.splice(index,1);
          }
        })
        mapElements.forEach((element) => {
          let gaodeMapFeature = null;
          try {
            gaodeMapFeature = element.addToMap(this.map, this.mapCoordSys)
          }catch (e) {
            console.error(e)
            warningMessage("要素有误：",element.mapData.name)
          }
          this.feature.page.push(gaodeMapFeature);
          gaodeMapFeature.clearEvents("click");
          this.addClickEvents(gaodeMapFeature, element);
        })
      },
    },
    elementInTop: {
      handler(mapElements) {
        this.feature.top.forEach((item,index)=>{
          const flag = mapElements.forEach(element=>{
            return item.getExtData().id === element.mapData.id;
          })
          if(flag===undefined){
            item.remove();
            this.feature.top.splice(index,1);
          }
        })
        mapElements.forEach((element) => {
          let gaodeMapFeature = null;
          try {
            gaodeMapFeature = element.addToMap(this.map, this.mapCoordSys)
          }catch (e) {
            console.error(e)
            warningMessage("要素有误：",element.mapData.name)
          }
          this.feature.top.push(gaodeMapFeature);
          gaodeMapFeature.clearEvents("click");
          this.addClickEvents(gaodeMapFeature, element);
        })
      },
    },
    mapCoordSys:{
      handler(newVal,oldVal){
        console.log("coodys changed",newVal,oldVal)
        if(newVal!==oldVal) {
          this.getAllDataInStore();
         let {lng,lat}=this.map.getCenter()
          if(newVal===MyMapOpt.MapCoordSys.CJ02&&oldVal===MyMapOpt.MapCoordSys.GPS){
            this.map.setCenter(convert_gps84_To_Gcj02([lng,lat]))
          }
          if(newVal===MyMapOpt.MapCoordSys.GPS&&oldVal===MyMapOpt.MapCoordSys.CJ02){
            this.map.setCenter(convert_gcj02_To_Gps84([lng,lat]))
          }
        }
      }
    }
  },
  methods: {
    ...mapMutations("MapInDatabase",{
      clearAllElementInPage:"CLEAR_ALL_ELEMENT_IN_PAGE",
      clearDataInTop:"CLEAR_ALL_ELEMENT_IN_TOP",
    }),
    ...mapMutations("EditElement",{
      setAddType:"SET_ADD_TYPE",
    }),
    ...mapActions("EditElement",[
      "setElement","openEdit","closeEdit"
    ]),
    ...mapActions("MapInDatabase",{
      addDataToPage:"addDataToPage",
      addDataToTop:"addDataToTop",
    }),
    // region 通过窗口修改数据
    /**
     * 打开修改窗口
     * @param row 编辑的要素
     */
    openEditDialog(row) {
      let editData = row.getCopy()
      this.setElement(editData);
      this.openEdit(MyMapOpt.DialogType.EditData);
    },
    /**
     * 关闭修改窗口
     */
    closeEditDialog() {
      this.editDialogData.visible = false
    },
    /**
     * 关闭修改窗口，并修改数据
     */
    saveEditDialog() {
      const editElement = this.editElement;
      let updatePage = false , updateTop = false ;
      const originElement = this.elementInPage.find(item=>item.mapData.id===editElement.mapData.id)||
          this.elementInTop.find(item=>item.mapData.id===editElement.mapData.id)
      console.log("originElement",originElement,"editElement",editElement)
      if(editElement.mapData.top
          ||(!editElement.mapData.top&&originElement.mapData.top))
        updateTop = true;
      this.elementInPage.forEach(item=>{
        if(item.mapData.id === editElement.mapData.id){
          updatePage = true;
        }
      })
      this.elementInTop.forEach(item=>{
        if(item.mapData.id === editElement.mapData.id){
          updateTop = true;
        }
      })
      if(updatePage)
        this.getElementInPage()
      if(updateTop)
        this.getElementInTop()
    },
    /**
     * 关闭修改窗口，并删除数据
     */
    deleteEditDialog() {
      this.deleteMapData(this.editElement);
      this.closeEditDialog();
      this.getElementInPage();
    },
    // endregion

    /**
     * 开启新增窗口
     */
    openAddDialog() {
      this.openEdit(MyMapOpt.DialogType.AddData);
    },
//度°分′秒″转度
    ToDigital(arr) {
      console.log(arr)
      let flag = arr[0]>0
      let strDu=parseFloat(arr[0]), strFen=parseFloat(arr[1]), strMiao=parseFloat(arr[2])
      let len = 6
      // len = (len > 6 || typeof (len) == "undefined") ? 6 : len;//精确到小数点后最多六位
      strDu = (typeof (strDu) == "undefined" || strDu == "") ? 0 : strDu;
      strFen = (typeof (strFen) == "undefined" || strFen == "") ? 0 : strFen / 60;
      strMiao = (typeof (strMiao) == "undefined" || strMiao == "") ? 0 : strMiao / 3600;
      let digital
      if(flag)
        digital = strDu + strFen + strMiao;
      else
        digital = strDu - strFen - strMiao
      // let result = parseFloat(digital.toFixed(len))
      let result = digital
      console.log("convert",arr,result)
      return result;
    },
    //度转度°分′秒″
    ToDegrees(val) {
      console.log(val)
      if (typeof (val) == "undefined" || val == "") {
        return "";
      }
      let flag = val > 0

      //没有转换为度分秒的数
      let other = Math.abs(val);
      var strDu = parseInt(other);//获取度
      // other = other-strDu;
      other = other%1
      var strFen = 0;
      var strMiao = 0;
      if (other!==0) {
        strFen = parseInt(other * 60)
        other = other * 60 % 1
        if (other!==0) {
          strMiao = other * 60
          /*i = strMiao.indexOf('.');
          strMiao = strMiao.substring(0, i + 4);//取到小数点后面三位*/
          // strMiao = parseFloat(strMiao.toFixed(3));//精确小数点后面两位
          if(strMiao-0.01<0){
            strMiao=0
          }
          if(60-strMiao-0.01<0){
            strDu+=1
            if(strDu===60){
              strFen+=1
            }
            strMiao=0
          }
        }
      }
      if(!flag){
        strDu=-strDu
      }
      console.log("convert",val,[strDu, strFen, strMiao])
      return [strDu, strFen, strMiao];
    },

// endregion

    // region 通过鼠标添加数据
    /**
     * 开启鼠标添加数据
     * @param type
     */
    startMouseAddData(type) {
      this.canChangeLayer=false
      this.mouseToolData.open = true
      this.mouseToolData.mouseTool = new AMap.MouseTool(this.map);
      this.mouseToolData.type = type
      const that = this
      this.mouseToolData.mouseTool.on('draw', function (e) {
        that._data.mouseToolData.overlays.push(e.obj);
      })
      switch (type) {
        case MyMapOpt.MapType.Marker: {
          this.mouseToolData.mouseTool.marker({
            //同Marker的Option设置
          });
          break;
        }
        case MyMapOpt.MapType.Polyline: {
          this.mouseToolData.mouseTool.polyline({
            strokeColor: '#80d8ff'
            //同Polyline的Option设置
          });
          break;
        }
        case MyMapOpt.MapType.Polygon: {
          this.mouseToolData.mouseTool.polygon({
            fillColor: '#00b0ff',
            strokeColor: '#80d8ff'
            //同Polygon的Option设置
          });
          break;
        }
      }
      //移除事件
      this.map.getAllOverlays().forEach(this.removeClickEvents)
    },
    /**
     * 关闭鼠标添加数据
     * @param isSave
     */
    stopMouseAddData(isSave) {
      if (isSave) {
        let opt;
        let mapData;
        switch (this.mouseToolData.type) {
          case MyMapOpt.MapType.Polygon:
            var path = [];
            for (let i = 0; i < this.mouseToolData.overlays.length; i++) {
              path.push(this.mouseToolData.overlays[i].getOptions().path)
            }
            const polygon = new Polygon({
              path,
              fillColor: getRandomColor(),
              strokeColor: getRandomColor(),
              fillOpacity: 0.5
            })
            mapData = new MapData({
              type: MyMapOpt.MapType.Polygon,
              top: false,
              name: this.mouseToolData.name || MyMapOpt.MapType.Polygon + Date.now(),
              coordsys:this.mapCoordSys
            })
            opt = new PolygonData({mapData, polygon});
            break;
          case MyMapOpt.MapType.Polyline:
            var path = [];
            for (let i = 0; i < this.mouseToolData.overlays.length; i++) {
              path.push(this.mouseToolData.overlays[i].getOptions().path)
            }
            const polyline = new Polyline({
              path,
              strokeColor: getRandomColor()
            })
            mapData = new MapData({
              type: MyMapOpt.MapType.Polyline,
              top: false,
              name: this.mouseToolData.name || MyMapOpt.MapType.Polyline + Date.now(),
              coordsys:this.mapCoordSys
            })
            opt = new PolylineData({mapData, polyline})
            break;
          case MyMapOpt.MapType.Marker:
            const position = this.mouseToolData.overlays[0].getPosition().toJSON()
            mapData = new MapData({
              type: MyMapOpt.MapType.Marker,
              top: false,
              name: this.mouseToolData.name || MyMapOpt.MapType.Marker + Date.now(),
              coordsys:this.mapCoordSys
            })
            const marker = new Marker({
              position
            })
            opt = new MarkerData({mapData, marker})
            break;
        }
        opt.upload().then(result => {
          if (result) {
            this.getElementInPage()
          }
        })
      } else {
        //取消修改后同样更新数据-->添加要素点击事件
        this.getElementInPage()
      }
      this.mouseToolData.type = ""
      this.mouseToolData.overlays = []
      this.mouseToolData.open = false
      this.mouseToolData.name = ""
      this.mouseToolData.mouseTool.close(true)
      this.canChangeLayer=true

    },
    // endregion


    // region 鼠标点击事件管理
    /**
     * 添加点击事件
     * @param feature GaodeMap中需要添加的事件的feature
     * @param item feature对应的MyMap对象
     */
    addClickEvents(feature, item) {
      feature.on('click', () => {
        this.openEditDialog(item)
      })
    },
    /**
     * 解除事件绑定
     * @param feature
     */
    removeClickEvents(feature) {
      feature.clearEvents("click");
      /*var clickEvents = feature.getEvents().click;
      if (typeof (clickEvents) !== "undefined") {
        clickEvents.forEach(eventOb => {
          feature.off("click", eventOb.fn)
        })
      }*/
    },
    // endregion

    // region 获取数据，并添加到地图
    /**
     * 更新
     * @param map
     */
    updateMap(map) {
      this.map = map
    },
    async getElementInPage() {
      this.clearAllElementInPage();
      const result = await reqGetMapdataCount()
      if (requestIsSuccess(result)) {
        this.pageData.count = requestGetData(result);
        if(this.pageData.count<=0) {
          warningMessage("暂无数据")
          return
        }
        if (Math.ceil(this.pageData.count / this.pageData.pageSize) < this.pageData.currentPage) {
          console.log("当前页无数据，跳转到第一页")
          this.pageData.currentPage = Math.ceil(this.pageData.count / this.pageData.pageSize)
        }
        const mapData = await reqGetMapdataByPage(this.pageData.currentPage, this.pageData.pageSize)
        if (requestIsSuccess(mapData)) {
          const dataList = requestGetData(mapData).map(getMapDateByType)
          await this.addDataToPage(dataList)
        }
      }
    },
    async getElementInTop() {
      this.clearDataInTop()
      const mapData = await reqGetMapDataTop()
      if (requestIsSuccess(mapData)) {
        let dataList = await requestGetData(mapData).map(getMapDateByType)
        await this.addDataToTop(dataList)
      }
    },
    async getAllDataInStore() {
      await this.getElementInPage()
      await this.getElementInTop()
    },
/*    updateCoordsy(coordys){
      this.mapCoordSys=coordys
    },*/
    handleCurrentPageChange(page){
      this.pageData.currentPage=page
      this.getElementInPage()
    },
    handlePageSizeChange(size) {
      this.pageData.pageSize=size;
      this.getElementInPage()
    },
    //endregion

    //region JSON管理
    /**
     * 导入json 通过json文件添加数据
     * @param event
     */
    addJsonFile(event) {
      event.target.files[0].text().then(target => {
        const data = JSON.parse(target);
        var myMap = getMapDateByType(data)
        myMap.upload();
        this.getAllDataInStore();
      })
      this.stopMouseAddData(false);
    },
    /**
     * 导出json数据
     * @param row
     */
    exportJSON(row) {
      row.getJSON();
    },
    //endregion

    // region 其他
    /**
     * 移除tag
     * @param tag
     */
    handleClose(tag) {
      tag.mapData.top = false
      tag.update().then(result => {
        if (result) {
          this.getElementInTop()
        }
      })
    },

    /**
     * 删除该行数据
     * @param row
     */
    async deleteMapData(row) {
      row.deleteElement().then(result => {
        if (requestIsSuccess(result)) {
          this.getElementInPage();
        }
      })
    },
    /**
     * 移动到某一行的数据
     * @param row
     */
    moveTo(row) {
      row.moveTo(this.map)
    },
    updateCoordsy(coordsy){
      this.mapCoordSys=coordsy

    },
    // endregion
  },

  created() {
    /*if(typeof this.map=== "undefined")
      this.initMap();*/
    this.getAllDataInStore()
  },
  computed:{
    MyMapOpt() {
      return MyMapOpt
    },
    ...mapState("EditElement", {
      editVisible : "visible",
      dialogType: "dialogType",
      editElement:"element"
    }),
    ...mapState("MapInDatabase",{
      //保存在数据库中的element
      elementInPage:"elementInDatabase",
      //top置顶的数据
      elementInTop:"topElementInDatabase",
    }),
  }
}
</script>

<style scoped>


.input-card{

}

.in{
  /*font-size: 18px;*/
  width: 75%;
  outline: none;
  border: none;
  /*border-bottom: 1px solid #dcd4fe;*/
  color: #2b2b33;
  margin-left: 1%;
  margin-bottom: 10px;
  padding: 8px 0;
  display: inline-block;
}

.vCode{
  color: #333131;
  /*background: #e5dce1;*/
  width: 15%;
  height: 40px;
  /*border-radius: 15px;*/
  border: none;
}
.rightInput{
  width: 100%;
}
.input-item{
  height: 2.2rem;
}
.btn{
  width: 6rem;
  margin: 0 1rem 0 2rem;
}
.input-text{
  width: 4rem;
  margin-right:1rem;
}
.tb{
  width: 100%;
}
.editAttr{
  margin: 2px;
}
.td-name{
  width: 4em;
}
.td-data{
  float: left;
  margin: 2px;
}
</style>